/*
 * 2006-04-18 Li Ximing, Zhang Yanbo - Create.
 */
package com.hd123.rumba.log;

import java.lang.reflect.Field;
import java.util.Date;

import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.runtime.IManager;
import com.hd123.rumba.runtime.IPersistent;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.user.IUser;

/**
 * 实体日志 | 生成器 | 实现类
 * 
 * @author lxm
 * @author zhangyanbo
 * 
 */
public class EntityLogger {

  /* 公共事件常量 */
  public static final String EVENT_ADDNEW = "新增";
  public static final String EVENT_MODIFY = "修改";
  public static final String EVENT_REMOVE = "删除";
  public static final String EVENT_DELETE = "删除（标记）";
  public static final String EVENT_UNDELETE = "恢复删除";

  private IEntityLogMgr logMgr = null;

  public EntityLogger(IManager manager) {
    super();
    this.manager = manager;
    try {
      logMgr = (IEntityLogMgr) NamingMgr.getInstance().lookupMgr(IEntityLogMgr.class);
    } catch (BusinessException e) {
      e.printStackTrace();
    }
  }

  private IManager manager = null;
  private IPersistent entity = null;
  private Class entityConstClass = null;
  private IUser operator = null;
  private Date time = null;
  private String settleNo = null;

  /** 属性：实体对象 */
  public IPersistent getEntity() {
    return entity;
  }

  /** 属性：实体对象 */
  public void setEntity(IPersistent entity) {
    this.entity = entity;
  }

  /** 属性：实体对象的常量类 */
  public Class getEntityConstClass() {
    return entityConstClass;
  }

  /** 属性：实体对象的常量类 */
  public void setEntityConstClass(Class entityConstClass) {
    this.entityConstClass = entityConstClass;
  }

  /**
   * 属性：实体对象的接口类
   * 
   * @deprecated
   */
  public Class getEntityIntfClass() {
    return entityConstClass;
  }

  /**
   * 属性：实体对象的接口类
   * 
   * @deprecated
   */
  public void setEntityIntfClass(Class entityIntfClass) {
    this.entityConstClass = entityIntfClass;
  }

  /** 属性：管理员对象 */
  public IManager getManager() {
    return manager;
  }

  /** 属性：管理员对象 */
  public void setManager(IManager manager) {
    this.manager = manager;
  }

  /** 属性：操作员 */
  public IUser getOperator() {
    return operator;
  }

  /** 属性：操作员 */
  public void setOperator(IUser operator) {
    this.operator = operator;
  }

  /** 属性：操作时间 */
  public Date getTime() {
    return time;
  }

  /** 属性：操作时间 */
  public void setTime(Date time) {
    this.time = time;
  }

  /**
   * 属性：月度结转期号，允许空<br>
   * 注：对于rumba而言，暂时没有任何含义，保留为未来扩展。
   */
  public String getSettleNo() {
    return settleNo;
  }

  /**
   * 属性：月度结转期号，允许空<br>
   * 注：对于rumba而言，暂时没有任何含义，保留为未来扩展。
   */
  public void setSettleNo(String settleNo) {
    this.settleNo = settleNo;
  }

  /** @deprecated */
  public IEntityLog log(String event, Integer oldState, Integer newState, String message)
      throws BusinessException {
    return this.log(event, newState, message);
  }

  /**
   * 写日志。
   * 
   * @param event
   *          事件信息。
   * @param newState
   *          实体新状态。
   * @param message
   *          消息。
   * @return IEntityLog
   */
  public IEntityLog log(String event, Integer newState, String message) throws BusinessException {
    if (this.operator == null)
      throw new BusinessException(this.getClass() + ":属性operator不可为空。");
    try {
      IEntityLog entityLog = logMgr.createLog();
      if (this.operator.getDomain() == null) {
        IDomainMgr domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
        entityLog.setDomain(domainMgr.getRootDomain());
      } else
        entityLog.setDomain(this.operator.getDomain());
      entityLog.setOperator(this.operator.getNameCode());
      entityLog.setTime(this.time);
      if (settleNo != null)
        entityLog.setSettleNo(settleNo);
      entityLog.setEvent(event);
      entityLog.setMessage(message);
      entityLog.setManagerClass(this.manager.getClass().getName());
      entityLog.setManagerCaption(this.manager.getCaption());
      if (this.entity != null)
        entityLog.setEntityUuid(this.entity.getUuid());
      if (this.entityConstClass != null)
        entityLog.setEntityCaption(fetchEntityCaption());
      entityLog.setNewState(newState);
      logMgr.save(entityLog);
      return entityLog;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  protected String fetchEntityCaption() {
    Field[] fields = this.entityConstClass.getDeclaredFields();
    for (int i = 0; i < fields.length; i++)
      try {
        if ("CAPTION_CLASS".equals(fields[i].getName()))
          return (String) fields[i].get(null);
      } catch (IllegalArgumentException e) {
      } catch (IllegalAccessException e) {
      }
    return this.entityConstClass.getSimpleName();
  }
}
